"""
Generic state machine. 
"""

class StateMachine:
   def __init__(self, _debug=False):
      self.data = None
      self.states = []
      self.debug = _debug
   
   def push(self, _state):
      """ This method pushes a state onto the stack, making it the top and the method top()
           will return this on the next call. 
      """
      if self.debug:
         print "Debug >>> Pushing " + _state.name + " onto the stack."
      self.states.append(_state)
      
   def pop(self):
      """ This method removes the current state from the top of the stack. The state below it  will 
          automaticly be retured by the next call to the top() method. returns the pop'd state
      """
      try:
         states = self.top()
         self.states.pop(-1)
         return data
      except:
         print "stack empty"
         return None
      
   def count(self):
      """ Returns the number of states in the stack """
      return len(self.states)
      
   def top(self):
      """ returns the top state in the stack (the active one)  TODO: Must clean this code. The stack can
          run out of states and this needs to be handled.
      """
      try:
         return self.states[-1]
      except:
         print "stack empty"
         return None
         
   
   def dump(self):
      """ Dumps some data about the stack.
      """
      try:
         print "Stack: length=", len(self.data)
         for x in self.states:
            print x.name, " run=", x.run
         topState = self.top()
         print "Top is " + topState.name
      except:
         print "stack empty"
      
   def ready(self):
      """ This method checks to see if the topstate has its ready flag set. """
      try:
         top_state = self.top()
         return top_state.run
      except:
         print "stack empty"
   
   # TODO: this is worthless. please remove.
   def need_init(self):
      """ Checks to see if the state needs to be inited.
      """
      try:
         top_state = self.top()
         return top_state.needsInit
      except:
         print "stack empty"
      
   
   
   def cleanup(self):
      """ TODO: This function needs to be able to look through the stack
          and pick out states that are left behind or that have had their
          ready flag changed by the current state.
          
          Cleans up the stack. 
      """
      if self.ready():
         pass
   
   def __del__(self):
      """ generic destructor 
      """
      pass
      
